
#include "Application.h"
#include "TitleView.h"
#include "Unit.h"
#include "hgeUtil.h"
#include <math.h>
#include <iostream>
#include <fstream>

Application *Application::mainApp = 0;
HGE *hge;
HTEXTURE guiBackground, leftArrow, rightArrow;
HEFFECT menuSound;

//
// Constructor
//

Application::Application()
{
	hge = 0;
	if(ReadConfigFile())
	{
		LoadHGE();
		CreateHGEWindow();
	}
}

//
// GetApp
//

Application *Application::GetApp()
{
	if(!mainApp)
		mainApp = new Application();
	return mainApp;
}

//
// ReadConfigFile
//

bool Application::ReadConfigFile()
{
	fstream file; 
	file.open("config.ini", ios_base::in);
	if(!file.is_open()) return false;

	char header[256];

	file >> header;
	file >> screenWidth;
	file >> header;
	file >> screenHeight;
	file >> header;
	file >> fullScreen;

	return true;
}

//
// Exec
//

void Application::Exec()
{
	if(!hge)
	{
		MessageBox(NULL, "Failed to load config.ini", "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
		return;
	}

	if(hge->System_Initiate() && LoadData())
	{
		// Create the GUI
		title = new TitleView();
		view = title;
		enteringNewView = true;

		// Start the app
		hge->System_Start();

		// Free GUIs
		delete title; title = 0;
		view = 0;
	}
	else
	{
		MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
	}

	// Clean up and shutdown
	hge->System_Shutdown();
	hge->Release();
}

//
// LoadHGE
//

void Application::LoadHGE()
{
	// Get HGE interface
	hge = hgeCreate(HGE_VERSION);

	// Set up log file, frame function, render function and window title
	hge->System_SetState(HGE_LOGFILE, "logfile.log");
	hge->System_SetState(HGE_FRAMEFUNC, Application::_ProcessFrame);
	hge->System_SetState(HGE_RENDERFUNC, Application::_RenderFrame);
	hge->System_SetState(HGE_TITLE, "Turret Defense");
}

//
// CreateWindow
//

void Application::CreateHGEWindow()
{
	// Set up video mode
	hge->System_SetState(HGE_SHOWSPLASH, false);
	hge->System_SetState(HGE_WINDOWED, !fullScreen);
	hge->System_SetState(HGE_SCREENWIDTH, (int)screenWidth);
	hge->System_SetState(HGE_SCREENHEIGHT, (int)screenHeight);
	hge->System_SetState(HGE_SCREENBPP, 32);
}

//
// LoadData
//

bool Application::LoadData()
{
	// Load fonts
	smallFont = new hgeFont("data/font2.fnt");
	largeFont = new hgeFont("data/font1.fnt");

	// Load cursor
	cursorTex = hge->Texture_Load("data/cursor.png");
	cursor = new hgeSprite(cursorTex, 0, 0, 32, 32);

	// Gui background
	guiBackground = hge->Texture_Load("data/guiBackground.png");

	// Menu sound
	menuSound = hge->Effect_Load("data/menu.wav");

	// IntegerItem
	leftArrow = hge->Texture_Load("data/leftArrow.png");
	rightArrow = hge->Texture_Load("data/rightArrow.png");

	// Loads in the unit data
	LoadUnits();

	return (smallFont && largeFont && cursorTex && cursor && 
					guiBackground && menuSound && leftArrow && rightArrow);
}

//
// LoadUnits
//

void Application::LoadUnits()
{
	Unit::texture = hge->Texture_Load("data/enemies.png");
	new Unit(0,   0,  26,  17);
	new Unit(0,  18,  30,  48);
	new Unit(0,  49,  37,  91);
	new Unit(0,  92,  35, 139);
	new Unit(0, 140,  62, 182);
	new Unit(0, 183,  38, 229);
	new Unit(0, 230,  42, 275);
	new Unit(0, 276,  35, 329);
	new Unit(0, 330,  38, 356);
	new Unit(0, 358,  48, 413);
	new Unit(0, 414,  57, 493);
	new Unit(0, 494,  61, 533);
	new Unit(0, 534,  70, 582);
	new Unit(0, 583, 142, 653);
}

//
// RenderFrame
//

bool Application::RenderFrame()
{
	// Skip rendering frame if entering new view
	if(enteringNewView) return false;

	// Begin rendering quads.
	// This function must be called
	// before any actual rendering.
	hge->Gfx_BeginScene();

	// Render the current view
	view->Render();
	
	// Draw Frame rate
	largeFont->SetColor(0xFFFFFFFF);
	largeFont->printf(5, screenHeight-30, HGETEXT_LEFT, "FPS:%d", hge->Timer_GetFPS());

	// End rendering and update the screen
	hge->Gfx_EndScene();

	// Continue
	return false;
}

//
// ProcessFrame
//

bool Application::ProcessFrame()
{
	// Enter new process
	if(enteringNewView)
		view->Enter();

	// Process view
	View *lastView = view;
	view = view->Process();

	// Check to see if a new view is returned
	enteringNewView = view != lastView;

	// Continue if new view isn't zero
	return (view == 0);
}

//
// RenderCursorSprite
//

void Application::RenderCursorSprite() const
{
	if(hge->Input_IsMouseOver())
	{
		float x, y;
		hge->Input_GetMousePos(&x, &y);
		cursor->Render(x, y);
	}
}
